// //工厂方法  Factory Method模式解决“单个对象”的需求变化  
//用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型，紧耦合关系会导致软件的脆弱。
// class AbstractPersonRepo {  //   这其实是提供一个接口
//   getList() {
//     throw new Exception("抽象方法不能直接调用")
//   }
//   getItem() {
//     throw new Exception("抽象方法不能直接调用")
//   }
// }
// class RealPersonRepo extends AbstractPersonRepo {
//   getList() {
//     return [{
//       id: 1,
//       name: "张三"
//     }]
//   }
//   getItem() {
//     return {
//       id: 1,
//       name: "张三"
//     }
//   }
// }
// class MockPersonRepo extends AbstractPersonRepo {
//   getList() {
//     return [{
//       id: 1,
//       name: "张三（模拟）"
//     }]
//   }
//   getItem() {
//     return {
//       id: 1,
//       name: "张三（模拟）"
//     }
//   }
// }

// class RepoFactory {
//   createPersonRepo() {
//     throw new Exception("抽象方法不能直接调用")
//   }
// }
// class RealRepoFactory extends RepoFactory {
//   createPersonRepo() {
//     return new RealPersonRepo()
//   }
// }
// class MockRepoFactory extends RepoFactory {
//   createPersonRepo() {
//     return new MockPersonRepo()
//   }
// }
// const CONFIG = {
//   factoryClass: MockRepoFactory
// }

// const loadAllPerson = (repo) => {
//   return repo.getList()
// }


// // const factory = new MockRepoFactory()
// const factory = Reflect.construct(CONFIG.factoryClass, [])   //Reflect.construct其实就是实例化构造函数，他的第三个参数为一个超类，前面的类会继承后面的类
// const allPerson = loadAllPerson(factory.createPersonRepo())

//////////////////////////////对象的形式////////////////////////
let personRepo = {}
personRepo.realPersonRepo = {
  getList() {
    return [{
      id: 1,
      name: "张三"
    }]
  },
  getItem() {
    return {
      id: 1,
      name: "张三"
    }
  }
}
personRepo.mockPersonRepo = {
  getList() {
    return [{
      id: 1,
      name: "张三（模拟）"
    }]
  },
  getItem() {
    return {
      id: 1,
      name: "张三（模拟）"
    }
  }
}

const CONFIG = {
  factoryName: 'mock'
}
createPersonRepo(factoryName) {
  return personRepo[`${factoryName || CONFIG.factoryName}PersonRepo`]
}
const loadAllPerson = (repo) => {
  return repo.getList()
}
const allPerson = loadAllPerson(createPersonRepo())

//抽象工厂方法
var AbstractFactory = function (subType, superType) {
  //判断抽象工厂种是否有这个抽象类＼
  if (typeof (AbstractFactory[superType]) == 'function') {
    //缓存类
    function F() {};
    //继承父类属性和方法
    F.protorype = new AbstractFactory[superType]();
    //将子类constructor指向子类
    subType.constructor = subType;
    //子类原型继承＂父类＂
    subType.prototype = new　 F();
  } else {
    //不存在该抽象类抛出错误
    throw new Error('未创建该抽象类');
  }
}

// //小汽车抽象类
AbstractFactory.Car = function () {
  this.type = 'Car';
}
AbstractFactory.Car.prototype = {
  getPrice: function () {
    return new Error('抽象方法不能调用！');
  }
}
//宝马汽车类
var BMW = function (price, speed) {
  this.price = price;
  this.speed = speed;
}
//抽象工厂实现对Car抽象类的继承
AbstractFactory(BMW, 'Car');
BMW.prototype.getPrice = function () {
  return this.price;
}




